package judesart.app.server;

import java.util.ArrayList;
import java.util.List;

import judesart.app.client.controller.ProjectController;
import judesart.app.domain.Artist;
import judesart.app.domain.Artwork;
import judesart.app.domain.Note;
import judesart.app.domain.Project;
import judesart.app.domain.ProjectArtwork;
import judesart.app.domain.User;
import judesart.app.repository.ArtistDAO;
import judesart.app.repository.ArtworkDAO;
import judesart.app.repository.ProjectDAO;
import judesart.app.service.UserService;
import judesart.app.shared.ArtworkShort;
import judesart.app.shared.SearchResult;
import judesart.app.shared.ValidationException;
import judesart.common.bean.ApplicationContextProvider;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class ProjectControllerImpl extends RemoteServiceServlet implements
        ProjectController
{

    private static final long serialVersionUID = 1L;

    private final static Log LOGGER = LogFactory.getLog(ProjectControllerImpl.class);

    ArtistDAO artistDAO = ApplicationContextProvider.getCtx().getBean(
            ArtistDAO.class);
    UserService userService = ApplicationContextProvider.getCtx().getBean(
            UserService.class);
    ArtworkDAO artworkDAO = ApplicationContextProvider.getCtx().getBean(
            ArtworkDAO.class);
    ProjectDAO projectDAO = ApplicationContextProvider.getCtx().getBean(
            ProjectDAO.class);

    @Override
    public Project createProject(Project project) throws ValidationException
    {
        project.setArtistId(getArtistId());
        return projectDAO.createProject(project);
    }

    @Override
    public void deleteProject(Long projectId)
    {
        projectDAO.deleteProject(projectId);
    }

    @Override
    public void deleteSketchFromProject(Long projectId, Long imageId)
    {
        projectDAO.deleteSketchFromProject(getProject(projectId), imageId);
    }

    @Override
    public Project getProject(Long id)
    {
        Project project = projectDAO.findProjectById(id);
        setTransientFields(project);
        return project;
    }

    @Override
    public SearchResult<Project> searchProjects(int startAt, int maxElements)
    {
        Long artistId = getArtistId();
        int count = projectDAO.countProjects(artistId);
        List<Project> results = projectDAO.findProjects(artistId, startAt,
                maxElements);
        setTransientFields(results);
        return new SearchResult<Project>(new ArrayList<Project>(results), count);
    }

    private void setTransientFields(List<Project> results)
    {
        for (Project project : results)
        {
            setTransientFields(project);
        }
    }

    private void setTransientFields(Project project)
    {
        if (project.getArtworks() != null && project.getArtworks().size() > 0)
        {
            for (ProjectArtwork projectArtwork : project.getArtworks())
            {
                LOGGER.debug(" > setTransientFields 1 ["
                        + projectArtwork.getArtworkId() + "]");
                Artwork artwork = artworkDAO.findArtworkById(projectArtwork.getArtworkId());
                if (artwork.getPhotos() != null
                        && artwork.getPhotos().size() > 0)
                {
                    LOGGER.debug(" > setTransientFields 2 ["
                            + projectArtwork.getArtworkId() + "]");
                    projectArtwork.setMainImageId(artwork.getPhotos().get(0).getImageId());
                }
                projectArtwork.setMainImageTitle(artwork.getTitle());
                LOGGER.debug(" > setTransientFields 3 ["
                        + projectArtwork.getMainImageId() + "]");
            }
        }
    }

    private Long getArtistId()
    {
        Long artistId;
        User user = userService.getCurrentUser();
        if (user != null)
        {
            Artist artist = artistDAO.findArtistByUserId(user.getId());
            artistId = artist.getId();
        } else
        {
            artistId = null;
        }
        return artistId;
    }

    @Override
    public Project updateProject(Project project) throws ValidationException
    {
        return projectDAO.updateProject(project);
    }

    @Override
    public String updateSketchDescription(String sketchKey, String description)
    {
        return projectDAO.updateSketchDescription(sketchKey, description).getDescription();
    }

    @Override
    public String findSketchKeyByImageId(Long imageId)
    {
        return projectDAO.findSketchKeyByImageId(imageId);
    }

    @Override
    public void deletePhotoFromProject(Long projectId, Long imageId)
    {
        projectDAO.deletePhotoFromProject(getProject(projectId), imageId);
    }

    @Override
    public String findPhotoKeyByImageId(Long imageId)
    {
        return projectDAO.findProjectKeyByImageId(imageId);
    }

    @Override
    public String updatePhotoDescription(String photoKey, String description)
    {
        return projectDAO.updatePhotoDescription(photoKey, description).getDescription();
    }

    @Override
    public void addArtworkToProject(Long projectId, Long artworkId)
    {
        LOGGER.debug(" >> addArtworkToProject [" + projectId + "]");
        Project project = projectDAO.findProjectById(projectId);
        Artwork artwork = artworkDAO.findArtworkById(artworkId);
        projectDAO.addArtworkToProject(project, artwork);
    }

    @Override
    public List<ArtworkShort> findProjectArtworksImages(Long projectId)
    {
        if (projectId == null)
        {
            return new ArrayList<ArtworkShort>();
        }
        Project project = projectDAO.findProjectById(projectId);
        List<ProjectArtwork> projArts = project.getArtworks();
        List<ArtworkShort> imageIds = new ArrayList<ArtworkShort>();
        for (ProjectArtwork projectArtwork : projArts)
        {
            Artwork artwork = artworkDAO.findArtworkById(projectArtwork.getArtworkId());
            ArtworkShort xort = new ArtworkShort();
            xort.setId(artwork.getId());
            if (artwork.getPhotos() != null && artwork.getPhotos().size() > 0)
            {
                xort.setImageId(artwork.getPhotos().get(0).getImageId());
            }
            xort.setTitle(artwork.getTitle());
            imageIds.add(xort);
        }
        return imageIds;
    }

    @Override
    public void deleteArtworkFromProject(Long projectId, Long artworkId)
    {
        Project project = projectDAO.findProjectById(projectId);
        Artwork artwork = artworkDAO.findArtworkById(artworkId);
        projectDAO.deleteArtworkFromProject(project, artwork);
    }

    @Override
    public Note addNoteToProject(Long projectId, String text)
    {
        Project project = projectDAO.findProjectById(projectId);
        project = projectDAO.addNoteToProject(project, text);
        return project.getNotes().get(project.getNotes().size() - 1);
    }

    @Override
    public void deleteNoteFromProject(Long projectId, String notekey)
    {
        Project project = projectDAO.findProjectById(projectId);
        projectDAO.deleteNoteFromProject(project, notekey);
    }

    @Override
    public void updateNoteInProject(Note note)
    {
        projectDAO.updateNoteText(note.getKey(), note.getText());
    }

    @Override
    public List<Project> findAllUserProjects(Long userId)
    {
        Artist artist = artistDAO.findArtistByUserId(userId);
        List<Project> results = new ArrayList<Project>(projectDAO.findProjects(
                artist.getId(), 0, 100));
        return results;
    }

}
